﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using AzureTracer.Common;
using AzureTracer.Resources;
using AzureTracer.Views.Controls;
using Krempel.WP7.Core.Controls;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Microsoft.Phone.Tasks;

namespace AzureTracer.Views
{
    public partial class MainPage : PhoneApplicationPage
    {
        bool _isNewPageInstance = false;
        UIElement _lastItemSelect;
        double _actualVerticalOffset;

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // enable tilt effect for multiselect items    
            TiltEffect.TiltableItems.Add(typeof(MultiselectItem));

            this.Loaded += OnLoaded;
            _isNewPageInstance = true;
        }

        #region DependencyProperty InLines (TextBlock)
        public static string GetInlines(TextBlock obj)
        {
            return (string)obj.GetValue(InlinesProperty);
        }

        public static void SetInlines(TextBlock obj, string value)
        {
            obj.SetValue(InlinesProperty, value);
        }

        public static readonly DependencyProperty InlinesProperty =
            DependencyProperty.RegisterAttached("Inlines", typeof(List<Inline>), typeof(TextBlock), new PropertyMetadata(OnInlinesPropertyChanged));

        private static void OnInlinesPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var textBlock = obj as TextBlock;
            var inlines = e.NewValue as List<Inline>;

            if (textBlock != null && inlines != null)
            {
                textBlock.Inlines.Clear();
                inlines.ForEach(line => textBlock.Inlines.Add(line));
            }
        }
        #endregion

        #region DependencyProperty ActualMultiselectList (MultiselectList)
        public MultiselectList ActualMultiselectList
        {
            get { return (MultiselectList)GetValue(ActualMultiselectListProperty); }
            set { SetValue(ActualMultiselectListProperty, value); }
        }

        public static readonly DependencyProperty ActualMultiselectListProperty =
            DependencyProperty.Register("ActualMultiselectList", typeof(MultiselectList), typeof(PhoneApplicationPage), new PropertyMetadata(null));

        #endregion

        void OnLoaded(object sender, System.Windows.RoutedEventArgs e)
        {
            ApplicationBar.MatchOverriddenTheme();
            if (_actualVerticalOffset != 0)
            {
                var actualScrollView = ActualMultiselectList.GetVisualDescendents<ScrollViewer>().FirstOrDefault();
                actualScrollView.ScrollToVerticalOffset(_actualVerticalOffset);
            }
        }

        protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
        {
            base.OnBackKeyPress(e);
            e.Cancel = true;
            if (searchControl.IsVisible)
                searchControl.IsVisible = false;
            else if (ActualMultiselectList.IsSelectionEnabled)
                ActualMultiselectList.IsSelectionEnabled = false;
            else
                e.Cancel = false;
        }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            if (e.NavigationMode != NavigationMode.Back)
            {
                State["searchControlIsVisible"] = searchControl.IsVisible;
                var actualScrollView = ActualMultiselectList.GetVisualDescendents<ScrollViewer>().FirstOrDefault();
                if (actualScrollView != null)
                    State["ActualVerticalOffset"] = actualScrollView.VerticalOffset;
                State["PivotSelectedIndex"] = PivotContent.SelectedIndex;
            }
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (_lastItemSelect != null) // Clear last item animation
            {
                ItemTurnstileTransition.SetIsTurnstileItem(_lastItemSelect, false);
                ItemTurnstileTransition.SetItemContinuumMode(_lastItemSelect, ContinuumModeEnum.None);
                _lastItemSelect = null;
            }

            if (!_isNewPageInstance) return;

            if (State.Count != 0)
            {
                PivotContent.SelectedIndex = (int)State["PivotSelectedIndex"];
                if (State.ContainsKey("ActualVerticalOffset"))
                    _actualVerticalOffset = (double)State["ActualVerticalOffset"];

                if ((bool)State["searchControlIsVisible"])
                    searchControl.ShowKeyboard();
                State.Clear();
            }
            _isNewPageInstance = false;
        }

        private void SelectList_IsSelectionEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            bool isSelectionEnabledChanged = (bool)e.NewValue;

            AppBar.CanInvalidate = false;

            SendMailMultipleIconButton.Visibility =
            DeleteMultipleIconButton.Visibility =
            ReadMultipleMenuItem.Visibility =
            UnreadMultipleMenuItem.Visibility =
                isSelectionEnabledChanged ?
                Visibility.Visible : Visibility.Collapsed;

            EnableSelectionIconButton.Visibility =
            RefreshIconButton.Visibility =
            SearchIconButton.Visibility =
            AllReadMenuItem.Visibility =
            SettingsMenuItem.Visibility =
                 isSelectionEnabledChanged ?
                Visibility.Collapsed : Visibility.Visible;

            if (isSelectionEnabledChanged)
                SelectList_SelectionChanged(sender, null);

            AppBar.CanInvalidate = true;
            AppBar.Invalidate();
        }

        private void SelectList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            MultiselectList selectList = (MultiselectList)sender;

            SendMailMultipleIconButton.IsEnabled =
            DeleteMultipleIconButton.IsEnabled =
            ReadMultipleMenuItem.IsEnabled =
            UnreadMultipleMenuItem.IsEnabled =
               selectList.SelectedItems.Count != 0;
        }

        private void GenericPivot_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count == 0) return;

            PivotItem pivotItem = e.AddedItems[0] as PivotItem;

            if (ActualMultiselectList != null && ActualMultiselectList.IsSelectionEnabled)
                ActualMultiselectList.IsSelectionEnabled = false;

            MultiselectList multiselectList = ((Grid)pivotItem.Content).Children[0] as MultiselectList;
            if (multiselectList != null)
                ActualMultiselectList = multiselectList;
        }

        private void EnableSelection_Click(object sender, EventArgs e)
        {
            if (ActualMultiselectList != null)
                ActualMultiselectList.IsSelectionEnabled = true;
        }

        private void DisableSelection_Click(object sender, EventArgs e)
        {
            if (ActualMultiselectList != null)
                ActualMultiselectList.IsSelectionEnabled = false;
        }

        private void ListItemGrid_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            _lastItemSelect = (UIElement)sender;
            ItemTurnstileTransition.SetIsTurnstileItem(_lastItemSelect, true);
            ItemTurnstileTransition.SetItemContinuumMode(_lastItemSelect, ContinuumModeEnum.ForwardOut);
        }

        private void Hyperlink_Click(object sender, RoutedEventArgs e)
        {
            WebBrowserTask webBroser = new WebBrowserTask();
            webBroser.Uri = new System.Uri(labels.WhoToTracesUrl);
            webBroser.Show();
        }

        private void DeleteMenuItem_Click(object sender, RoutedEventArgs e)
        {
            MenuItem menuItem = (MenuItem)sender;
            ICommand delayedCommand = menuItem.Command;
            menuItem.Command = null;

            ContextMenu contextMenu = (ContextMenu)menuItem.Parent;
            Grid ListItemGrid = (Grid)contextMenu.Owner;

            Storyboard story = ListItemGrid.Resources["UnloadItemStoryboard"] as Storyboard;
            story.BeginTime = TimeSpan.FromSeconds(0.2);
            story.Completed += (s, args) =>
                   delayedCommand.Execute(menuItem.CommandParameter);
            story.Begin();
        }

        private void DeleteMultiple_Click(object sender, EventArgs e)
        {
            object[] selectedItems = new object[ActualMultiselectList.SelectedItems.Count];
            ActualMultiselectList.SelectedItems.CopyTo(selectedItems, 0);

            DisableSelection_Click(sender, e);

            BindableApplicationBarIconButton deleteMultipleButton = (BindableApplicationBarIconButton)sender;
            ICommand delayedCommand = deleteMultipleButton.Command;
            deleteMultipleButton.Command = null;

            int pendingAnimation = selectedItems.Count();

            for (int i = 0; i < selectedItems.Count(); i++)
            {
                var multiselectItem = ActualMultiselectList.ItemContainerGenerator.ContainerFromItem(selectedItems[i]);
                Grid ListItemGrid = multiselectItem.GetVisualDescendents<Grid>().Where(x=> x.Name=="ListItemGrid").FirstOrDefault();
                Storyboard story = ListItemGrid.Resources["UnloadItemStoryboard"] as Storyboard;
                story.Completed += (s, args) =>
                    {
                        pendingAnimation--;
                        if (pendingAnimation == 0)
                        {
                            delayedCommand.Execute(selectedItems.ToList());
                            deleteMultipleButton.Command = delayedCommand;
                        }
                    };
                story.BeginTime = TimeSpan.FromSeconds(0.1*i);
                story.Begin();
            }
        }
    }
}